package com.hero.take.util;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import java.util.regex.Pattern;

public class NumberHelpper {
    public static BigDecimal obj2BigDecimal(Object obj) {
        if (obj == null) return BigDecimal.ZERO;
        if (!isNumber(obj.toString())) return BigDecimal.ZERO;
        return new BigDecimal(obj.toString());
    }

    public static String numberToStrByLength(int num, int length) {
        String r = String.valueOf(num);
        int l = String.valueOf(num).length();
        for (int i = 0; i < length - l; i++) {
            r = "0" + r;
        }
        return r;
    }

    public static boolean isInteger(String str) {
        if (StringUtils.isBlank(str)) return false;
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    public static boolean isNumber(String str) {
        if (StringUtils.isBlank(str)) return false;
        Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
        return pattern.matcher(str).matches();
    }

    public static Integer strToInt(String str) {
        return strToInt(str, null);
    }

    public static Integer strToInt(String str, Integer defaultValue) {
        return isInteger(str) ? Integer.valueOf(str) : defaultValue;
    }

    /**
     * 取反
     *
     * @param value
     * @return
     */
    public static BigDecimal reverse(BigDecimal value) {
        if (value == null) return BigDecimal.ZERO;
        return reduce(BigDecimal.ZERO, value);
    }

    public static String float2NumStr(float value) {
        NumberFormat ddf1 = NumberFormat.getNumberInstance();
        ddf1.setMaximumFractionDigits(2);
        String str = ddf1.format(value);
        if (str.endsWith(".0")) return str.replace(".0", "");
        else return str;
//        return NumberHelpper.decimal2(BigDecimal.valueOf(num)).toString().replace(".00", "");
    }

    public static String decimalStr(BigDecimal value) {
        return formatTosepara(decimal2(value, BigDecimal.ZERO));
    }

    public static BigDecimal decimal1(BigDecimal value) {
        return decimal1(value, null);
    }

    public static BigDecimal decimal1(BigDecimal value, BigDecimal defaultValue) {
        if (value == null) value = defaultValue;
        if (value == null) return value;
        return value.setScale(1, RoundingMode.HALF_UP);
    }

    public static BigDecimal decimal2(BigDecimal value) {
        return decimal2(value, BigDecimal.ZERO);
    }

    public static BigDecimal decimal2(BigDecimal value, BigDecimal defaultValue) {
        if (value == null) value = defaultValue;
        if (value == null) return value;
        return value.setScale(2, RoundingMode.HALF_UP);
    }

    public static BigDecimal decimal4(BigDecimal value) {
        return decimal4(value, BigDecimal.ZERO);
    }

    public static BigDecimal decimal4(BigDecimal value, BigDecimal defaultValue) {
        if (value == null) value = defaultValue;
        if (value == null) return value;
        return value.setScale(4, RoundingMode.HALF_UP);
    }

    /**
     * value1大于value2
     *
     * @param value1
     * @param value2
     * @return
     */
    public static boolean more(BigDecimal value1, int value2) {
        if (value1 == null) return false;
        return value1.compareTo(BigDecimal.valueOf(value2)) > 0;
    }

    /**
     * value1大于value2
     *
     * @param value1
     * @param value2
     * @return
     */
    public static boolean more(BigDecimal value1, BigDecimal value2) {
        if (value1 == null) value1 = BigDecimal.ZERO;
        if (value2 == null) value2 = BigDecimal.ZERO;
        return value1.compareTo(value2) > 0;
    }

    /**
     * value大于0
     *
     * @param value
     * @return
     */
    public static boolean more0(BigDecimal value) {
        if (value == null) value = BigDecimal.ZERO;
        return value.compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * value大于等于0
     *
     * @param value
     * @return
     */
    public static boolean moreAndEquals0(BigDecimal value) {
        if (value == null) value = BigDecimal.ZERO;
        return value.compareTo(BigDecimal.ZERO) >= 0;
    }

    /**
     * value1大于等于value2
     *
     * @param value1
     * @param value2
     * @return
     */
    public static boolean moreAndEquals(BigDecimal value1, BigDecimal value2) {
        if (value1 == null) value1 = BigDecimal.ZERO;
        if (value2 == null) value2 = BigDecimal.ZERO;
        return value1.compareTo(value2) >= 0;
    }

    /**
     * value1小于value2
     *
     * @param value1
     * @param value2
     * @return
     */
    public static boolean less(BigDecimal value1, BigDecimal value2) {
        if (value1 == null) value1 = BigDecimal.ZERO;
        if (value2 == null) value2 = BigDecimal.ZERO;
        return value1.compareTo(value2) < 0;
    }

    /**
     * value小于0
     *
     * @param value
     * @return
     */
    public static boolean less0(BigDecimal value) {
        if (value == null) value = BigDecimal.ZERO;
        return value.compareTo(BigDecimal.ZERO) < 0;
    }

    /**
     * value1小于等于0
     *
     * @param value
     * @return
     */
    public static boolean lessAndEquals0(BigDecimal value) {
        if (value == null) value = BigDecimal.ZERO;
        return value.compareTo(BigDecimal.ZERO) <= 0;
    }

    /**
     * value1小于等于value2
     *
     * @param value1
     * @param value2
     * @return
     */
    public static boolean lessAndEquals(BigDecimal value1, BigDecimal value2) {
        if (value1 == null) value1 = BigDecimal.ZERO;
        if (value2 == null) value2 = BigDecimal.ZERO;
        return value1.compareTo(value2) <= 0;
    }

    /**
     * value1等于value2
     *
     * @param value1
     * @param value2
     * @return
     */
    public static boolean equals(BigDecimal value1, BigDecimal value2) {
        if (value1 == null) value1 = BigDecimal.ZERO;
        if (value2 == null) value2 = BigDecimal.ZERO;
        return value1.compareTo(value2) == 0;
    }

    /**
     * value等于0
     *
     * @param value
     * @return
     */
    public static boolean equals0(BigDecimal value) {
        if (value == null) value = BigDecimal.ZERO;
        return value.compareTo(BigDecimal.ZERO) == 0;
    }

    /**
     * value1减去value2
     *
     * @param value1
     * @param values
     * @return
     */
    public static float reduce(float value1, Float... values) {
        if (values == null || values.length == 0) return value1;
        List<String> arr = ListHelpper.strToList(Float.toString(value1), ".");
        int len = ListHelpper.count(arr) == 2 ? arr.get(1).length() : 0;
        BigDecimal result = BigDecimal.valueOf(value1);
        for (Float value : values) {
            if (value == null) continue;
            arr = ListHelpper.strToList(Float.toString(value), ".");
            len = ListHelpper.count(arr) == 2 && arr.get(1).length() > len ? arr.get(1).length() : len;
            result = result.subtract(BigDecimal.valueOf(value));
        }
        return result.setScale(len, RoundingMode.HALF_UP).floatValue();
    }

    /**
     * value1减去value2
     *
     * @param value1
     * @param values
     * @return
     */
    public static BigDecimal reduce(BigDecimal value1, BigDecimal... values) {
        return decimal2(reduce4(value1, values));
    }

    /**
     * value1减去value2
     *
     * @param value1
     * @param values
     * @return
     */
    public static BigDecimal reduce4(BigDecimal value1, BigDecimal... values) {
        BigDecimal v1 = value1 == null ? BigDecimal.ZERO : value1;
        if (values == null || values.length == 0) return decimal2(v1);
        for (BigDecimal value : values) {
            if (value == null) continue;
            v1 = v1.subtract(value);//v1 - value.floatValue();
        }
        return decimal4(v1);
    }

    /**
     * value1减去value2的差大于0 则返回差，否则返回0
     *
     * @param value1
     * @param value2
     * @return
     */
    public static BigDecimal reduceMore0AndGet(BigDecimal value1, BigDecimal value2) {
        BigDecimal c = reduce(value1, value2);
        return more0(c) ? c : BigDecimal.ZERO;
    }

    /**
     * value百分比totalValue
     *
     * @param value
     * @param totalValue
     * @return
     */
    public static float percent(BigDecimal value, BigDecimal totalValue) {
        if (totalValue == null || equals0(totalValue)) return (float) 0.0;
        float valueFloat = value == null ? (float) 0 : value.floatValue();
        return float4((valueFloat / totalValue.floatValue()) * 100);
    }

    /**
     * value百分比totalValue
     *
     * @param value
     * @param totalValue
     * @return
     */
    public static float percent2(BigDecimal value, BigDecimal totalValue) {
        return float2(percent(value, totalValue));
    }

    /**
     * value百分比totalValue
     *
     * @param value
     * @param totalValue
     * @return
     */
    public static float percent(int value, int totalValue) {
        return percent(BigDecimal.valueOf(value), BigDecimal.valueOf(totalValue));
    }

    /**
     * value百分比totalValue
     *
     * @param value
     * @param totalValue
     * @return
     */
    public static float percent(float value, float totalValue) {
        return percent(BigDecimal.valueOf(value), BigDecimal.valueOf(totalValue));
    }

    /**
     * value1加上values
     *
     * @param value1
     * @param values
     * @return
     */
    public static BigDecimal add(BigDecimal value1, BigDecimal... values) {
        BigDecimal result = value1 == null ? BigDecimal.ZERO : value1;
        for (BigDecimal value : values) {
            if (value == null) continue;
            result = result.add(value);
//            result += value.floatValue();
        }
        return decimal2(result);
    }

    /**
     * value1乘上values
     *
     * @param value1
     * @param values
     * @return
     */
    public static BigDecimal multiply(BigDecimal value1, BigDecimal... values) {
        if (value1 == null) value1 = BigDecimal.ZERO;
        for (BigDecimal value : values) {
            if (value == null) continue;
            value1 = value1.multiply(value);
        }
        return decimal2(value1);
    }

    /**
     * value1乘上10000
     *
     * @param value1
     * @return
     */
    public static BigDecimal multiply10000(BigDecimal value1) {
        return multiply(value1, BigDecimal.valueOf(10000));
    }

    /**
     * value1除以values（除以0，返回被除数）
     *
     * @param value1
     * @param values
     * @return
     */
    public static BigDecimal divide(BigDecimal value1, BigDecimal... values) {
        return decimal2(divide4(value1, values));
    }

    /**
     * value1除以values（除以0，返回被除数）
     *
     * @param value1
     * @param values
     * @return
     */
    public static BigDecimal divide4(BigDecimal value1, BigDecimal... values) {
        if (value1 == null) value1 = BigDecimal.ZERO;
        for (BigDecimal value : values) {
            if (value == null || equals0(value)) continue;
            value1 = value1.divide(value, 4, BigDecimal.ROUND_HALF_UP);
        }
        return value1;
    }

    /**
     * value1除以10000
     *
     * @param value1
     * @return
     */
    public static BigDecimal divide10000(BigDecimal value1) {
        return divide(value1, BigDecimal.valueOf(10000));
    }

    /**
     * 保留4位小数
     *
     * @param value
     * @return
     */
    public static float float4(float value) {
        return BigDecimal.valueOf(value).setScale(4, RoundingMode.HALF_UP).floatValue();
    }

    /**
     * 保留2位小数
     *
     * @param value
     * @return
     */
    public static float float2(float value) {
        return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP).floatValue();
    }

    /**
     * 保留1位小数
     *
     * @param value
     * @return
     */
    public static float float1(float value) {
        return BigDecimal.valueOf(value).setScale(1, RoundingMode.HALF_UP).floatValue();
    }

    public final static String formatTosepara(BigDecimal data) {
        if (data == null || data.floatValue() == 0) return "0.00";
//        DecimalFormat df = new DecimalFormat("#,###.##");
        DecimalFormat df = new DecimalFormat("#,###.00");
        df.setRoundingMode(RoundingMode.HALF_UP);
        return df.format(data);
    }

    public static double fiveInFourOut(double num) {
        return new BigDecimal(num).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * double类型格式化（四舍五入）
     * 参考文献：https://blog.csdn.net/dearhuda/article/details/104327096
     *
     * @return
     */
    public static String doubleFormat(double num, int capacity) {
        NumberFormat nf = NumberFormat.getNumberInstance();
        //保留两位小数
        nf.setMaximumFractionDigits(capacity);
        //四舍五入
        nf.setRoundingMode(RoundingMode.UP);
        String str = nf.format(num);
        return str;
    }
}
